Add GitHub workflow and job metadata labels to runner pods#4256
Add GitHub workflow and job metadata labels to runner pods#4256halradaideh wants to merge 2 commits intoactions:masterfrom
Conversation
Add workflow metadata labels to runner pods for cost tracking
There was a problem hiding this comment.
Pull Request Overview
Adds GitHub workflow metadata labels to runner pods for cost allocation and tracking in GKE environments. This enables organizations to attribute GitHub Actions costs to specific repositories, workflows, and jobs through Kubernetes labels.
- Implements automatic labeling of runner pods with workflow metadata when jobs start
- Adds RBAC permissions for pod updates in both manager and kube mode roles
- Includes label value sanitization for Kubernetes compliance
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| cmd/ghalistener/worker/worker.go | Core implementation with pod labeling logic, sanitization function, and job handling updates |
| charts/gha-runner-scale-set/templates/manager_role.yaml | Adds update and patch verbs to pods rule for manager role |
| charts/gha-runner-scale-set/templates/kube_mode_role.yaml | Adds update and patch verbs to pods rule for kube mode role |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| reg := regexp.MustCompile(`[^a-zA-Z0-9._-]`) | ||
| sanitized := reg.ReplaceAllString(value, "-") | ||
|
|
||
| // Remove consecutive hyphens | ||
| reg = regexp.MustCompile(`-+`) | ||
| sanitized = reg.ReplaceAllString(sanitized, "-") |
There was a problem hiding this comment.
Consider compiling the regular expressions once as package-level variables instead of recompiling them on every function call. This will improve performance when the function is called frequently.
| sanitized = reg.ReplaceAllString(sanitized, "-") | ||
|
|
||
| // Ensure it starts and ends with alphanumeric character | ||
| sanitized = strings.Trim(sanitized, "-._") |
There was a problem hiding this comment.
After trimming characters, the result could be empty even if the original sanitized string wasn't empty, but the function only checks for empty strings before this step. This could result in multiple values being mapped to 'unknown' when they should have distinct sanitized values.
| sanitized = sanitized[:63] | ||
| sanitized = strings.Trim(sanitized, "-._") | ||
| } | ||
|
|
There was a problem hiding this comment.
After truncating and trimming, the sanitized string could become empty, but there's no check to handle this case. This could result in empty label values which are invalid in Kubernetes.
| // If empty after truncation and trimming, use a default value | |
| if sanitized == "" { | |
| sanitized = "unknown" | |
| } |
| "pod", pod.Name, | ||
| "labels", workflowLabels) | ||
|
|
||
| _, err = w.clientset.CoreV1().Pods(w.config.EphemeralRunnerSetNamespace).Update(ctx, pod, metav1.UpdateOptions{}) |
There was a problem hiding this comment.
Using Update() without checking resource version could lead to conflicts if the pod is modified by another process between Get() and Update(). Consider using Patch() instead or implementing retry logic with exponential backoff to handle update conflicts.
Problem
Organizations using GitHub Actions with self-hosted runners on GKE cannot attribute costs to specific repositories, workflows, or jobs because runner pods lack workflow metadata labels.
Solution
Automatically apply workflow metadata as pod labels when jobs start, enabling cost tracking through GKE's existing cost allocation infrastructure.
Reference: https://cloud.google.com/kubernetes-engine/docs/how-to/cost-allocations
Changes
Worker Implementation (
cmd/ghalistener/worker/worker.go):updatePodLabelsWithWorkflowMetadata()functionsanitizeLabelValue()for Kubernetes label validationHandleJobStarted()to apply labels when jobs startWithClientset()option for testabilityRBAC Permissions (
charts/gha-runner-scale-set/templates/manager_role.yaml):updateandpatchverbs to pods ruleLabels Applied
github.com/repository: Repository name (sanitized)github.com/workflow: Workflow reference (sanitized)github.com/job: Job display name (sanitized)github.com/job-id: Unique job IDgithub.com/run-id: Workflow run IDExample Output
Key Features
Testing
Benefits
This enables organizations to track GitHub Actions costs at the repository, workflow, and job level using their existing GKE cost allocation setup.
disclaimer: this was developed isong Cursor AI, so it needs a proper review.